<template>
  <common-edit-dialog
    :title="title ? '编辑访问控制' : '新增访问控制'"
    :visible.sync="open"
    @cancel="cancel"
    @submit="submitForm"
    :buttonLoading="buttonLoading"
    width="900px"
  >
    <el-form
      :model="form"
      label-width="80px"
      ref="form"
      :rules="rules"
      @submit.native.prevent
    >
      <el-row :gutter="18">
        <el-col :span="24">
          <el-form-item label="管控规则" prop="url">
            <common-input v-model="form.url" placeholder="支持通配或单个URL" />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="控制类型" prop="controlType">
            <el-select
              v-model="form.controlType"
              placeholder="请选择"
              style="width: 100%"
              clearable
              @change="controlTypeChange"
            >
              <el-option
                v-for="item in controlTypeList"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24" v-if="form.controlType === '5'">
          <el-form-item label="工作日" prop="workDayList">
            <div style="display: flex">
              <el-checkbox-group
                v-model="form.workDayList"
                style="min-width: 540px"
              >
                <el-checkbox label="Mon">周一</el-checkbox>
                <el-checkbox label="Tue">周二</el-checkbox>
                <el-checkbox label="Wed">周三</el-checkbox>
                <el-checkbox label="Thu">周四</el-checkbox>
                <el-checkbox label="Fri">周五</el-checkbox>
                <el-checkbox label="Sat">周六</el-checkbox>
                <el-checkbox label="Sun">周日</el-checkbox>
              </el-checkbox-group>
              <el-time-picker
                is-range
                style="width: 100%"
                v-model="form.timeValue"
                format="HH:mm"
                value-format="HH:mm"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                placeholder="选择时间范围"
              >
              </el-time-picker>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="24" v-if="form.controlType === '6'">
          <el-form-item label="管控值" prop="timestampValue">
            <common-input-number
              v-model="form.timestampValue"
              placeholder="请输入"
              style="width: calc(100% - 30px)"
            /><span style="padding-left: 8px">秒</span>
          </el-form-item>
        </el-col>
        <el-col
          :span="24"
          v-if="form.controlType === '1' || form.controlType === '2'"
        >
          <el-form-item
            :rules="rules.controlValue"
            v-for="(item, index) in form.controlList"
            :key="index"
            :prop="'controlList.' + index + '.value'"
            :label="`访问源 ${index === 0 ? '' : index}`"
          >
            <div class="control">
              <common-input v-model="item.value" placeholder="请输入" />
              <div
                v-if="form.controlType === '1' || form.controlType === '2'"
                style="display: flex"
              >
                <content-tip :tipType="'control_ip'"></content-tip>
                <el-button
                  v-if="index <= 0"
                  class="control-button"
                  type="primary"
                  icon="plus"
                  plain
                  @click="handleAddControlValue"
                  >新增</el-button
                >
                <el-button
                  v-if="index !== 0"
                  class="control-button"
                  type="danger"
                  plain
                  @click="handleDeleteControlValue(index)"
                  >删除</el-button
                >
              </div>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="24" v-if="form.controlType === '0'">
          <el-form-item label="访问量" prop="controlNum">
            <common-input-number
              v-model="form.controlNum"
              placeholder="请输入"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24" v-if="form.controlType === '3'">
          <el-form-item label="秘钥" prop="controlPwd">
            <common-pwd-input
              placeholder="请输入"
              style="width: 100%"
              v-model="form.controlPwd"
              :maxlength="16"
            ></common-pwd-input>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="备注">
            <common-input
              v-model="form.remark"
              placeholder="请输入备注"
              type="textarea"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </common-edit-dialog>
</template>
<script>
import { add, edit } from "@/api/apisecurity/visitcontrol/index";
import BaseList from "@/mixins/BaseList.vue";
import ContentTip from "@/views/analysisCenter/log/ContentTip/index.vue";
import CommonInputNumber from "@/components/CommonInputNumber/index.vue";
import { min } from "@antv/util";
import dayjs from "dayjs";

export default {
  components: { ContentTip, CommonInputNumber },
  name: "add",
  mixins: [BaseList],

  data() {
    const validateWorkDay = (rule, value, callback) => {
      if (
        this.form.workDayList.length &&
        this.form.timeValue &&
        this.form.timeValue.length
      ) {
        callback();
      } else {
        callback(new Error("请选择星期和时间"));
      }
    };
    const checkIP = (rule, value, callback) => {
      if (this.form.controlList.filter((f) => f.value === value).length > 1) {
        callback(new Error("IP不能重复，请重新输入"));
      } else {
        callback();
      }
    };
    const validateIPs = (rule, value, callback) => {
      if (value === "" || typeof value === "undefined" || value == null) {
        callback(new Error());
      } else {
        let values = value.split(",");
        const ipv4s_1 = new RegExp(
          "^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])-(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$"
        );
        const ipv4s_2 = new RegExp(
          "^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$"
        );
        const ipv6 = new RegExp(
          "^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))(%.+)?\\s*$"
        );
        values.map((item) => {
          if (ipv4s_1.test(item) || ipv4s_2.test(item) || ipv6.test(item)) {
            callback();
          } else {
            callback(new Error());
          }
        });
      }
    };
    return {
      form: {
        controlNum: 0,
        controlPwd: "",
        controlType: "",
        url: "",
        controlValue: "",
        remark: "",
        controlList: [{ value: "" }],
        workDay: "",
        timestampValue: null,
        timeValue: [],
        workDayList: [],
      },

      rules: {
        controlType: [
          { required: true, message: "请选择控制类型", trigger: "blur" },
        ],
        url: [{ required: true, message: "请输入管控规则", trigger: "blur" }],
        timestampValue: [
          {
            required: true,
            message: "请输入管控值",
            trigger: "blur",
          },
        ],
        workDayList: [
          {
            required: true,
            validator: validateWorkDay,
            trigger: "blur",
          },
        ],
        controlNum: [
          {
            required: true,
            message: "请输入访问量",
            trigger: "blur",
          },
        ],
        controlPwd: [
          {
            required: true,
            message: "请输入秘钥",
            trigger: "blur",
          },
          {
            min: 16,
            max: 16,
            message: "请输入16位的秘钥",
            trigger: "blur",
          },
        ],
        controlValue: [
          { required: true, message: "请输入访问源", trigger: "blur" },
          { required: true, validator: checkIP, trigger: "blur" },
          {
            required: true,
            message: "IP错误，支持IPV4/IPV6格式",
            validator: validateIPs,
            trigger: "blur",
          },
        ],
      },
      open: false,
      buttonLoading: false,
      title: false,

      controlTypeList: [
        { label: "限流", value: "0" },
        { label: "黑名单", value: "1" },
        { label: "白名单", value: "2" },
        { label: "签名", value: "3" },
        // { label: "二次认证", value: "4" },
        { label: "访问时间", value: "5" },
        { label: "时间戳", value: "6" },
      ],
    };
  },
  methods: {
    controlTypeChange(val) {
      if (val !== 1 && val !== 2) {
        this.form.controlList = [{ value: "" }];
      }

      if (this.form.controlType === "5") {
        this.form.timeValue = [
          dayjs().format("HH:mm"),
          dayjs().format("HH:mm"),
        ];
      }
      this.$refs.form.fields.map((i) => {
        if (i.prop === "controlList.0.value")
          this.$refs["form"].clearValidate(["controlList.0.value"]);
      });
      this.$refs["form"].clearValidate([
        "controlValue",
        "timestampValue",
        "workDayList",
        "controlPwd",
        "controlNum",
      ]);
    },
    handleAddControlValue() {
      this.form.controlList.push({});
    },
    handleDeleteControlValue(id) {
      this.form.controlList.splice(id, 1);
    },
    cancel() {
      this.open = false;
      this.resetForm();
    },
    resetForm() {
      this.form = {
        controlNum: 0,
        controlPwd: "",
        controlType: "",
        url: "",
        controlValue: "",
        remark: "",
        controlList: [{ value: "" }],
        workDay: "",
        timestampValue: null,
        workDayList: [],
        timeValue: [dayjs().format("HH:mm"), dayjs().format("HH:mm")],
      };
    },
    show(row) {
      this.open = true;
      if (row && row.id) {
        this.title = true;
        Reflect.ownKeys(this.form).forEach((k) => (this.form[k] = row[k]));
        this.form.controlType = row.controlType.toString();
        this.form.id = row.id;

        if (row.controlType === 0) {
          this.form.controlNum = parseInt(row.controlValue);
        }
        if (row.controlType === 1 || row.controlType === 2) {
          this.form.controlList = row.controlValue.split(",").reduce((r, c) => {
            r.push({ value: c });
            return r;
          }, []);
        }
        if (row.controlType === 3) {
          this.form.controlPwd = row.controlValue;
        }
        if (row.controlType === 4) {
          this.form.controlValue = row.controlValue;
        }
        this.form.workDayList = row.workDay.split(",");
        this.form.timeValue = [];
        this.form.timeValue.push(row.workBeginTime, row.workEndTime);
      } else {
        this.title = false;
        this.resetForm();
      }
    },

    submitForm() {
      this.$refs["form"].validate((valid) => {
        if (valid) {
          this.buttonLoading = true;
          if (this.form.controlType === "1" || this.form.controlType === "2") {
            let controlValue = [];
            this.form.controlList.map((item) => {
              controlValue.push(item.value);
            });
            this.form.controlValue = controlValue.join(",");
          }
          if (this.form.controlType === "0") {
            this.form.controlValue = this.form.controlNum;
          }
          ("");
          if (this.form.controlType === "3") {
            this.form.controlValue = this.form.controlPwd;
          }
          if (this.form.controlType === "4") {
            this.form.controlValue = "";
          }
          if (this.form.controlType === "5") {
            this.form.workBeginTime = this.form.timeValue[0];
            this.form.workEndTime = this.form.timeValue[1];
            this.form.workDay = this.form.workDayList.join(",");
          }
          if (this.form && this.form.id) {
            edit(this.form)
              .then((res) => {
                if (res && (res.code === 200 || res.rescode === 200)) {
                  this.$GlobalSuccessMessage("编辑成功");
                  this.$emit("getList");
                  this.resetForm();
                  this.open = false;
                } else {
                  this.$GlobalErrorConfirm("编辑失败", res.msg);
                }
              })
              .finally(() => {
                this.buttonLoading = false;
              });
          } else {
            add(this.form)
              .then((res) => {
                if (res && (res.code === 200 || res.rescode === 200)) {
                  this.$GlobalSuccessMessage("新增成功");
                  this.$emit("getList");
                  this.resetForm();
                  this.open = false;
                } else {
                  this.$GlobalErrorConfirm("新增失败", res.msg);
                }
              })
              .finally(() => {
                this.buttonLoading = false;
              });
          }
        }
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.control {
  display: flex;
  .control-button {
    margin-left: 8px;
  }
}
.el-checkbox {
  margin-right: 20px !important;
}
</style>
